


import MsgMgr from "../../lib/event/MsgMgr";
import TipMgr from "../../lib/tips/TipMgr";
import Tool from "../common/Tool";
import Cmd from "./Cmd";
import { NetPackage, decodeNetPackage, encodeNetPackage } from "./proto/NetPackage";

export enum SOCK_STATE {
    CONNECTING,
    SUCCESS,
    ERROR,
}

export class Socket {
    private _ws: WebSocket;

    private _session: string;
    public set session(val: string) {
        this._session = val;
    }
    public get session(): string {
        return this._session;
    }

    private static _errorHandler: any;
    public static set errorHandler(val) {
        Socket._errorHandler = val;
    }
    public static get errorHandler() {
        return Socket._errorHandler;
    }

    private _state: SOCK_STATE;
    public get state(): SOCK_STATE {
        return this._state;
    }
    
    private cache = [];
    private cacheCallInfo(cmd, callback) {
        if (!this.cache[cmd]) {
            this.cache[cmd] = [callback];
        } else if (this.cache[cmd].indexOf(callback) == -1) {
            this.cache[cmd].push(callback);
        }
    }

    //////////////////////////////////////////重连需要的数据
    private url:string;
    private resultCallback;

    public connect(url, func = null) {
        this.resultCallback = func;
        if ("WebSocket" in window) {
            this.url = url;
            this._ws = new WebSocket(url);
            //this._ws.binaryType = "arraybuffer";
            //申请一个WebSocket对象，参数是服务端地址，同http协议使用http://开头一样，WebSocket协议的url使用ws://开头，另外安全的WebSocket协议使用wss://开头
            this._ws.onopen = this.onOpen.bind(this);
            this._ws.onmessage = this.onMessage.bind(this);
            this._ws.onclose = this.onClose.bind(this);
            this._ws.onerror = this.onError.bind(this);
            console.warn("开始创建长链接 url:" + url);
            this._state = SOCK_STATE.CONNECTING;
            return this._ws;
        }
        
    }

    public reconnect(func) {
        console.warn("长链接重连")
        this._state = SOCK_STATE.CONNECTING;
        this.connect(this.url, func);
        
    }

    public clean() {
        this._ws && this._ws.close();
        this._ws = null;
    }

    public send(id, param, callback) {
        this.cacheCallInfo(id, callback);//存储回调信息
        let data = this.fillMsgData(id, param);
        this._ws.send(data);
        console.error("长链接发送消息:" + data);
    }

    public wait(id, callback) {
        this.cacheCallInfo(id, callback);//存储回调信息
    }

    private fillMsgData(msgId, params):string {
        let msg = {
            msgHead:{id:msgId},
            data:params
        }
        return JSON.stringify(msg)
    }

    private onOpen(e) {
        console.warn("长链接创建成功");
        // this.send(10003, {}, null);
        // setInterval(() => {
        //     this.send(10003, {}, null);
        // }, 60000)
        this._state = SOCK_STATE.SUCCESS;
        this.resultCallback && this.resultCallback(true);
        this.resultCallback = null;
    }

    private onMessage(msg: MessageEvent) {

        //let recvData = new Uint8Array(<ArrayBuffer>msg.data);
        //let data: NetPackage = decodeNetPackage(recvData);
        let data = JSON.parse(msg.data);
        let msgId = data.msgHead.id;
        MsgMgr.emit("MSG_ID_" + msgId + "_DATA", data);
        let arr = this.cache[msgId];
        if (arr) {
            delete this.cache[msgId];
            for (var i = 0; i < arr.length; i++) {
                arr[i] && arr[i](data);
            }
        } 
    }

    private onClose(e) {
        this._state = SOCK_STATE.ERROR;
        this.resultCallback && this.resultCallback(false);
        this.resultCallback = null;
    }

    private onError(e) {
        this._state = SOCK_STATE.ERROR;
        Socket.errorHandler && Socket.errorHandler();
        this.resultCallback && this.resultCallback(false);
        this.resultCallback = null;
    }

    private accept(rspd) {
        console.warn("长链接可以正常接收消息");
        
    }
}
